package cn.com.dashihui.api.service;

import java.util.ArrayList;
import java.util.List;

import com.jfinal.aop.Before;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;

import cn.com.dashihui.api.common.DispatchState;
import cn.com.dashihui.api.common.OrderCode;
import cn.com.dashihui.api.common.SysConfig;
import cn.com.dashihui.api.common.UserCode;
import cn.com.dashihui.api.dao.Goods;
import cn.com.dashihui.api.dao.Order;
import cn.com.dashihui.api.dao.OrderRefund;
import cn.com.dashihui.api.dao.User;
import cn.com.dashihui.kit.CommonKit;
import cn.com.dashihui.kit.DatetimeKit;
import cn.com.dashihui.kit.DoubleKit;
import cn.com.dashihui.kit.InviteCodeKit;

public class OrderService {
	/**
	 * 保存订单和订单清单
	 */
	public void save(Order order,String[] goodsidArray,String[] count) throws Exception{
		String orderNum = order.getStr("orderNum");
		//保存订单
		order.save();
		//批量保存商品列表
		Object[][] params = new Object[goodsidArray.length][15];
		String sql = "INSERT INTO t_bus_order_list(goodsid,orderNum,name,spec,shortinfo,price,thumb,isRebate,percent1,percent2,percent3,percent4,percent5,count,amount) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
		for(int i=0;i<goodsidArray.length;i++){
			String goodsid = goodsidArray[i];
			Goods goods=Goods.me().findFirst("SELECT * FROM t_bus_goods WHERE id=?",goodsid);
			params[i][0]=goodsid;
			params[i][1]=orderNum;
			params[i][2]=goods.getStr("name");
			params[i][3]=goods.getStr("spec");
			params[i][4]=goods.getStr("shortInfo");
			params[i][5]=goods.getDouble("sellPrice");
			params[i][6]=goods.getStr("thumb");
			//同时记录商品的返利配置情况
			params[i][7]=goods.getInt("isRebate");
			params[i][8]=goods.getDouble("percent1");
			params[i][9]=goods.getDouble("percent2");
			params[i][10]=goods.getDouble("percent3");
			params[i][11]=goods.getDouble("percent4");
			params[i][12]=goods.getDouble("percent5");
			
			params[i][13]=count[i];
			params[i][14]=goods.getDouble("sellPrice")*Integer.valueOf(count[i]).intValue();
		}
		Db.batch(sql, params, goodsidArray.length);
	}
	
	/**
	 * 用户查询各种状态的订单列表
	 */
	public Page<Record> findByPage(int storeid,int userid,int flag,int pageNum,int pageSize){
		if(flag==1){
			//1:待付款（“在线支付”、“未支付”、“正常”）
			String sql = "FROM t_bus_order bo LEFT JOIN t_dict_store ds ON bo.storeid=ds.id "
					+ "WHERE (bo.storeid=? OR bo.isSelf=1) AND bo.userid=? AND bo.payType=? AND bo.payState=? AND bo.orderState=? "
					+ "ORDER BY bo.createDate DESC";
			return Db.paginate(pageNum, pageSize, "SELECT bo.*,ds.title storeName ",sql,storeid,userid,OrderCode.OrderPayType.ON_LINE,OrderCode.OrderPayState.NO_PAY,OrderCode.OrderState.NORMAL);
		}else if(flag==2){
			//2：待发货（1：“在线支付+送货上门”、“已支付”、“未发货”、“正常”，2：“货到付款+送货上门”、“未发货”、“正常”）
			String sql = "FROM t_bus_order bo LEFT JOIN t_dict_store ds ON bo.storeid=ds.id WHERE (bo.storeid=? OR bo.isSelf=1) AND bo.userid=?"
					+ " AND ((bo.payType=? AND bo.payState=?)"
					+ " OR bo.payType=?)"
					+ " AND bo.takeType=? AND bo.deliverState=? AND bo.orderState=?"
					+ " ORDER BY bo.createDate DESC";
			return Db.paginate(pageNum, pageSize, "SELECT bo.*,ds.title storeName ",sql,storeid,userid,
					OrderCode.OrderPayType.ON_LINE,OrderCode.OrderPayState.HAD_PAY,
					OrderCode.OrderPayType.ON_DELIVERY,
					OrderCode.OrderTakeType.DELIVER,OrderCode.OrderDeliverState.NO_DELIVER,OrderCode.OrderState.NORMAL);
		}else if(flag==3){
			//3：待收/取货（1：“送货上门”、“已发货”、“正常”，2：“在线支付+门店自取”、“已支付”、“正常”，3：“货到付款+门店自取”、“正常”）
			String sql = "FROM t_bus_order bo LEFT JOIN t_dict_store ds ON bo.storeid=ds.id WHERE (bo.storeid=? OR bo.isSelf=1) AND bo.userid=?"
					+ " AND ((bo.takeType=? AND bo.deliverState=?)"
					+ " OR (bo.payType=? AND bo.payState=? AND bo.takeType=?)"
					+ " OR (bo.payType=? AND bo.takeType=?))"
					+ " AND bo.orderState=? ORDER BY bo.createDate DESC";
			return Db.paginate(pageNum, pageSize, "SELECT bo.*,ds.title storeName ",sql,storeid,userid,
					OrderCode.OrderTakeType.DELIVER,OrderCode.OrderDeliverState.HAD_DELIVER,
					OrderCode.OrderPayType.ON_LINE,OrderCode.OrderPayState.HAD_PAY,OrderCode.OrderTakeType.TAKE_SELF,
					OrderCode.OrderPayType.ON_DELIVERY,OrderCode.OrderTakeType.TAKE_SELF,
					OrderCode.OrderState.NORMAL);
		}else if(flag==4){
			//4：已完成（“已完成”）
			String sql = "FROM t_bus_order bo LEFT JOIN t_dict_store ds ON bo.storeid=ds.id WHERE (bo.storeid=? OR bo.isSelf=1) AND bo.userid=? AND bo.orderState=? ORDER BY bo.createDate DESC";
			return Db.paginate(pageNum, pageSize, "SELECT bo.*,ds.title storeName ",sql,storeid,userid,OrderCode.OrderState.FINISH);
		}else{
			//0：全部，不显示“删除”的订单
			String sql = "FROM t_bus_order bo LEFT JOIN t_dict_store ds ON bo.storeid=ds.id WHERE (bo.storeid=? OR bo.isSelf=1) AND bo.userid=? AND bo.orderState!=? ORDER BY bo.createDate DESC";
			return Db.paginate(pageNum, pageSize, "SELECT bo.*,ds.title storeName ",sql,storeid,userid,OrderCode.OrderState.DELETE);
		}
	}
	public Page<Record> findByPage_v132(int storeid,int userid,int flag,int pageNum,int pageSize){
		if(flag==1){
			//1：全部，不显示“删除”的订单
			String sql = "FROM t_bus_order bo LEFT JOIN t_dict_store ds ON bo.storeid=ds.id WHERE (bo.storeid=? OR bo.isSelf=1) AND bo.userid=? AND bo.orderState!=? ORDER BY bo.createDate DESC";
			return Db.paginate(pageNum, pageSize, "SELECT bo.*,ds.title storeName,(bo.amount - bo.redeemMoney) realPay ",sql,storeid,userid,OrderCode.OrderState.DELETE);
		}else if(flag==2){
			//2:待付款（“在线支付”、“未支付”、“正常”）
			String sql = "FROM t_bus_order bo LEFT JOIN t_dict_store ds ON bo.storeid=ds.id WHERE (bo.storeid=? OR bo.isSelf=1) AND bo.userid=? AND bo.payType=? AND bo.payState=? AND bo.orderState=? ORDER BY bo.createDate DESC";
			return Db.paginate(pageNum, pageSize, "SELECT bo.*,ds.title storeName,(bo.amount - bo.redeemMoney) realPay ",sql,storeid,userid,OrderCode.OrderPayType.ON_LINE,OrderCode.OrderPayState.NO_PAY,OrderCode.OrderState.NORMAL);
		}else if(flag==3){
			//3：待收/取货（1：“在线支付”、“已支付”、“正常”，2：“货到付款”、“正常”）
			String sql = "FROM t_bus_order bo LEFT JOIN t_dict_store ds ON bo.storeid=ds.id WHERE (bo.storeid=? OR bo.isSelf=1) AND bo.userid=?"
					+ " AND ((bo.payType=? AND bo.payState=?) OR bo.payType=?) AND bo.orderState=?"
					+ " ORDER BY bo.createDate DESC";
			return Db.paginate(pageNum, pageSize, "SELECT bo.*,ds.title storeName,(bo.amount - bo.redeemMoney) realPay ",sql,storeid,userid,
					OrderCode.OrderPayType.ON_LINE,OrderCode.OrderPayState.HAD_PAY,
					OrderCode.OrderPayType.ON_DELIVERY,OrderCode.OrderState.NORMAL);
		}else if(flag==4){
			//4：待评价（“已完成”、“未评价”）
			String sql = "FROM t_bus_order bo LEFT JOIN t_dict_store ds ON bo.storeid=ds.id WHERE (bo.storeid=? OR bo.isSelf=1) AND bo.userid=? AND bo.orderState=? AND bo.evalState=0 ORDER BY bo.createDate DESC";
			return Db.paginate(pageNum, pageSize, "SELECT bo.*,ds.title storeName,(bo.amount - bo.redeemMoney) realPay ",sql,storeid,userid,OrderCode.OrderState.FINISH);
		}
		return null;
	}
	
	/**
	 * 根据合单号修改订单的支付渠道
	 * @return
	 */
	public int updateOrderByMergerNum(String mergerNum, int payMethod){
		return Db.update("update t_bus_order set payMethod=? where mergerNum=?", mergerNum, payMethod);
	}
	
	/**
	 * 根据合单号查询出订单列表<br/>
	 * 排除已删除的订单
	 */
	public List<Order> getOrderListByMergerOrderNum(String orderNum){
		String sql = "SELECT * FROM t_bus_order WHERE (orderNum=? OR mergerNum=?) AND orderState!=? AND payType=1";
		return Order.me().find(sql,orderNum,orderNum,OrderCode.OrderState.DELETE);
	}
	
	/**
	 * 根据用户ID和订单号查询出订单<br/>
	 * 排除已删除的订单
	 */
	public Order getOrderByOrderNum(int userid,String orderNum){
		String sql = "SELECT bo.*,ds.title storeName,(bo.amount-bo.redeemMoney) realPay ";
		sql += "FROM t_bus_order bo LEFT JOIN t_dict_store ds ON bo.storeid=ds.id ";
		sql += "WHERE bo.userid=? AND bo.orderNum=? AND bo.orderState!=? ";
		return Order.me().findFirst(sql,userid,orderNum,OrderCode.OrderState.DELETE);
	}
	
	/**
	 * 根据用户ID和合单号查询出订单列表<br/>
	 * 排除已删除的订单
	 */
	public List<Order> getOrderListByMergerOrderNum(int userid,String orderNum){
		String sql = "SELECT * FROM t_bus_order WHERE userid=? AND (orderNum=? OR mergerNum=?) AND orderState!=? AND payType=1";
		return Order.me().find(sql,userid,orderNum,orderNum,OrderCode.OrderState.DELETE);
	}
	
	/**
	 * 根据订单号查询出订单<br/>
	 * 排除已删除的、已过期的订单
	 */
	public Order getOrderByOrderNum(String orderNum){
		return Order.me().findFirst("SELECT * FROM t_bus_order WHERE orderNum=? AND orderState!=? AND orderState!=?",orderNum,OrderCode.OrderState.DELETE,OrderCode.OrderState.EXPIRE);
	}
	
	/**
	 * 根据某一个订单的商品列表
	 */
	public List<Record> getGoodsListByOrderNum(String orderNum){
		return Db.find("SELECT goodsid,name,price,thumb,spec,count,amount FROM t_bus_order_list WHERE orderNum=?", orderNum);
	}
	
	/**
	 * 查询多个订单的商品列表
	 */
	public void getOrderGoodsList(List<Record> orderList){
		if(orderList!=null){
			//将所有订单的编号取出，以逗号分隔拼接
			String[] orderNumArr = new String[orderList.size()];
			for(int i=0;i<orderList.size();i++){
				orderNumArr[i] = "'"+orderList.get(i).getStr("orderNum")+"'";
			}
			//以订单编号为条件，查询所有订单的所有商品列表，并以订单号排序，方便遍历整理
			List<Record> allGoodsList = Db.find("SELECT orderNum,goodsid,name,price,thumb,spec,count,amount FROM t_bus_order_list WHERE orderNum IN ("+CommonKit.join(",", orderNumArr)+") ORDER BY orderNum");
			//遍历所有商品和订单，根据订单号将商品归类给对应的订单对象
			for(Record order : orderList){
				List<Record> goodsList = order.get("GOODSLIST");
				if(goodsList==null){
					goodsList = new ArrayList<Record>();
				}
				for(Record goods : allGoodsList){
					if(order.getStr("orderNum").equals(goods.getStr("orderNum"))){
						goodsList.add(goods);
					}
				}
				order.set("GOODSLIST",goodsList);
				order.set("STATEMENT",PropKit.get("constants.refund.statement"));
			}
		}
	}
	
	/**
	 * 查询退款订单列表
	 */
	public Page<Record> findRefundByPage(int storeid, int userid, int pageNum, int pageSize) {
		String sql = "SELECT bor.id,bor.refundnum,bor.type,bor.ordernum,bor.orderlistid,bor.amount,"
				+ "bor.state,bor.refusereason,bor.createdate,bor.updatedate,bo.amount orderamount";
		String sqlFrom = " FROM t_bus_order_refund bor INNER JOIN t_bus_order bo ON bor.orderNum = bo.orderNum AND (bo.storeid=? OR bo.isSelf=1) AND bo.userid = ? "
				+ " ORDER BY bor.createDate DESC";
		return Db.paginate(pageNum, pageSize, sql, sqlFrom, storeid, userid);
	}
	
	/**
	 * 根据订单号查询订单操作日志
	 */
	public List<Record> getLogListByOrderNum(String orderNum){
		return Db.find("SELECT type,user,action,content,createDate FROM t_bus_order_log WHERE orderNum=? ORDER BY createDate DESC", orderNum);
	}
	
	/**
	 * 用户催单
	 */
	@Before(Tx.class)
	public Order urgeOrder(int userid,String orderNum) throws Exception{
		if(Db.update("UPDATE t_bus_order SET urgeTimes=urgeTimes+1,urgeLastTime=now() WHERE userid=? AND orderNum=?",userid,orderNum)==1){
			return getOrderByOrderNum(orderNum);
		}
		throw new Exception("订单不存在");
	}
	
	/**
	 * 记录操作日志
	 */
	public void log(String orderNum, int type, String user, String action, String content){
		Db.update("INSERT INTO t_bus_order_log(orderNum,type,user,action,content) VALUES(?,?,?,?,?)",orderNum,type,user,action,content);
	}
	
	/**
	 * 更新用户实惠币
	 */
	public int updateUserMoney(int userid,double presentMoney, double previousMoney){
		return Db.update("UPDATE t_bus_user SET money = ? WHERE id=? AND money=?",presentMoney,userid,previousMoney);
	}
	
	/**
	 * 订单评价
	 */
	public boolean doEval(String orderNum, int userid, int eval1, int eval2, int eval3, String content){
		return Db.update("INSERT INTO t_bus_order_eval(orderNum,userid,eval1,eval2,eval3,content) VALUES(?,?,?,?,?,?)",orderNum,userid,eval1,eval2,eval3,content)==1;
	}
	
	/**
	 * 验证用户要购买的商品(店铺商品)
	 * 1.验证是否有商品已下架
	 * 2.验证是否有商品购买量已经超过了今日所限量
	 * 3.验证总金额是否与客户端的入参总金额相同
	 * @param goodsids 要验证的商品ID数组，以英文逗号分隔
	 * @param counts  要验证的商品的购买数量数组，以英文逗号分隔
	 * @return flag 验证结果，0：验证通过，1：有商品已下架，2：有商品已经超量，3：总金额对不上
	 */
	public int validate(int userid,int storeid,String goodsidsInpt,String countsInpt,String amountInpt){
		
		//1.准备数据
		//1.1.对goodsidArray和countArray转成数组，准备下一步进行遍历判断
		String[] goodsidArrayInpt = goodsidsInpt.split(","), countArrayInpt = countsInpt.split(",");
		//1.2.查询要验证的商品列表，并查出每个商品今日的销量（包括订单状态为正常的和已完成的，也就是只要下了单，没有取消、删除、过期，都算量）
		String sql = "SELECT A.id,A.type,A.name,A.sellPrice,A.state,A.urv,IFNULL(B.count,0) count FROM t_bus_goods A"
				+ " LEFT JOIN ("
					+ "SELECT SUM(BOL.count) count,BOL.goodsid"
					+ " FROM t_bus_order BO INNER JOIN t_bus_order_list BOL ON BO.orderNum=BOL.orderNum"
					+ " WHERE BO.userid=? AND (BO.storeid=? OR BO.isSelf=1) AND DATE_FORMAT(BO.createDate,'%Y-%m-%d')=DATE_FORMAT(now(),'%Y-%m-%d') AND (BO.orderState=? OR BO.orderState=?)"
					+ " GROUP BY BOL.goodsid"
				+ ") B ON A.id=B.goodsid"
				+ " WHERE A.id IN ("+goodsidsInpt+")";
		List<Record> list = Db.find(sql, userid,storeid,OrderCode.OrderState.NORMAL,OrderCode.OrderState.FINISH);
		//2.验证
		double amount = 0;
		for(Record goods : list){
			//商品ID
			int id = goods.getInt("id");
			//商品类型
			int type = goods.getInt("type");
			//商品类型
			double price = goods.getDouble("sellPrice");
			//商品限量
			int urv = goods.getInt("urv");
			//商品上下架状态
			int state = goods.getInt("state");
			//商品今日已购数量
			int count = goods.getBigDecimal("count").intValue();
			//2.1.验证是否有商品已经下架
			if(state==2){
				//有商品状态为2：已下架时，返回验证结果
				return 1;
			}
			//2.2.遍历对比所有的限量商品和一元购商品，验证（今日已购数量+本次所购数量）是否超过商品限量
			for(int i=0;i<goodsidArrayInpt.length;i++){
				int goodsidInpt = Integer.valueOf(goodsidArrayInpt[i]);
				int countInpt = Integer.valueOf(countArrayInpt[i]);
				if(goodsidInpt==id){
					if((type==3||type==4)&&(count+countInpt)>urv){
						return 2;
					}
					amount = DoubleKit.add(amount,DoubleKit.mul(price,countInpt));
					break;
				}
			}
		}
		//2.3.验证后台计算出来的总金额是否与客户端传进来的总金额相同
		if(amount!=Double.valueOf(amountInpt)){
			//如果不相同，则金额不匹配，返回验证结果
			return 3;
		}
		//3.验证通过
		return 0;
	}
	
	/**
	 * 取消订单，保存日志，并保存退款单信息
	 * @param order 订单信息
	 * @param reason 取消原因
	 * @param payType 支付类型
	 * @param payState 支付状态
	 * @param orderNum 订单编号
	 * @throws Exception 
	 */
	@Before(Tx.class)
	public void cancelOrder(Order order,String reason, int payType, int payState, String orderNum) throws Exception {
		//4.取消订单操作，并记录日志
		order.set("orderState", OrderCode.OrderState.CANCEL).set("reason", reason);
		if(order.update()){
			//4-1.判断该订单是否是“在线支付”和“已支付”
			if(payType == OrderCode.OrderPayType.ON_LINE && payState == OrderCode.OrderPayState.HAD_PAY) {
				//保存退款单信息
				//生成退款类订单的订单编号，以大写字母T开头
				String orderRefundNum = "T"+DatetimeKit.getFormatDate("yyyyMMddHHmmssSSS")+CommonKit.randomNum(3);
				if(!new OrderRefund()
						.set("refundNum", orderRefundNum)
						.set("orderNum", orderNum)
						.set("type", OrderCode.RefundType.CANCEL_ORDER)
						.set("amount", order.getDouble("amount"))
						.save()){
					throw new Exception("生成退款单失败！");
				}
			}
			//4-2.订单取消成功，记录订单操作日志并返回最新订单
			log(order.getStr("orderNum"),OrderCode.OrderLogType.CANCEL,"用户", OrderCode.OrderLogType.CANCEL_ACTION, "订单已取消");
			//查询订单的商品列表供页面展示
			order.put("goodsList", getGoodsListByOrderNum(order.getStr("orderNum")));
		} else {
			throw new Exception("订单取消失败！");
		}
	}
	
	/**
	 * 用户签收订单
	 */
	@Before(Tx.class)
	public void receiveOrder(Order order,User user) throws Exception {
		//更新订单状态
		order.set("orderState", OrderCode.OrderState.FINISH).set("signDate",DatetimeKit.getFormatDate("yyyy-MM-dd HH:mm:ss"));
		if(order.update()){
			String orderNum = order.getStr("orderNum");
			int takeType = order.getInt("takeType");
			if(takeType==OrderCode.OrderTakeType.DELIVER){
				//将配送员订单状态从“配送中”修改为“已完成”
				Db.update("UPDATE t_dict_store_seller_rel SET state=? WHERE orderNum=? AND state=?",DispatchState.FINISH,orderNum,DispatchState.DISPATCHING);
				//门店配送，用户签收
				log(order.getStr("orderNum"),OrderCode.OrderLogType.SIGN,"用户", OrderCode.OrderLogType.SIGN_ACTION, "商品已签收，感谢您在大实惠购物，欢迎再次光临！");
			}else if(takeType==OrderCode.OrderTakeType.TAKE_SELF){
				//将配送员订单状态从“待取货”修改为“已完成”
				Db.update("UPDATE t_dict_store_seller_rel SET state=? WHERE orderNum=? AND state=?",DispatchState.FINISH,orderNum,DispatchState.WAIT_GET);
				//上门自取，用户取货
				log(order.getStr("orderNum"),OrderCode.OrderLogType.GET,"用户", OrderCode.OrderLogType.GET_ACTION, "已取货，感谢您在大实惠购物，欢迎再次光临！");
			}
			//根据用户所购买的商品，进行分销处理
			rebate(order,user);
		}else{
			throw new Exception("订单接收失败！");
		}
	}
	
	private void rebate(Order order,User user) throws Exception{
		String orderNum = order.getStr("orderNum");
		//查询订单商品列表
		List<Record> goodsList = Db.find("SELECT goodsid,amount,isRebate,percent1,percent2,percent3,percent4,percent5 FROM t_bus_order_list WHERE orderNum=?", order.getStr("orderNum"));
		
		//所购开启分销商品总额
		double totalAmount = 0;
		
		//分销日志SQL
		String logSql = "INSERT INTO t_log_rebate(orderNum,goodsid,amount,percent1,money1,percent2,money2,percent3,money3,percent4,money4,percent5,money5) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)";
		
		//分销日志列表1
		List<Object[]> logParams1 = new ArrayList<Object[]>();
		//分销分成1（用户为普通用户，非黄金会员，也没有邀请用户，此时推荐人、DSH、社区享利）
		double[] rebate1 = new double[5];
		
		//分销日志列表2
		List<Object[]> logParams2 = new ArrayList<Object[]>();
		//分销分成2（用户为普通用户，非黄金会员，有邀请用户，此时推荐人、DSH、社区负责人、一级分销享利）
		double[] rebate2 = new double[5];
		
		//分销日志列表3
		List<Object[]> logParams3 = new ArrayList<Object[]>();
		//分销分成3（用户为黄金会员，也没有邀请用户，此时推荐人、DSH、社区负责人、二级分销享利）
		double[] rebate3 = new double[5];
		
		//分销日志列表4
		List<Object[]> logParams4 = new ArrayList<Object[]>();
		//分销分成4（用户为黄金会员，有邀请用户，此时推荐人、DSH、社区负责人、一级分销、二级分销享利）
		double[] rebate4 = new double[5];
		
		//遍历所有商品
		for(Record goods : goodsList){
			if(goods.getInt("isRebate")==1){
				int goodsid = goods.getInt("goodsid");
				//商品总金额
				double amount = goods.getDouble("amount");
				//商品设置“推荐人”返利比例
				double percent1 = DoubleKit.mul(goods.getDouble("percent1"),0.01);
				//商品设置“DSH”返利比例
				double percent2 = DoubleKit.mul(goods.getDouble("percent2"),0.01);
				//商品设置“社区负责人”返利比例
				double percent3 = DoubleKit.mul(goods.getDouble("percent3"),0.01);
				//商品设置“一级分销”返利比例
				double percent4 = DoubleKit.mul(goods.getDouble("percent4"),0.01);
				//商品设置“二级分销”返利比例
				double percent5 = DoubleKit.mul(goods.getDouble("percent5"),0.01);
				//累计本单中所有开启返利的商品的消费金额
				totalAmount = DoubleKit.add(totalAmount, amount);
				//用户为普通用户，非黄金会员，也没有邀请用户，此时推荐人、DSH、社区负责人享利
				rebate1[0] = DoubleKit.add(rebate1[0], DoubleKit.mul(amount,percent1));
				rebate1[1] = DoubleKit.add(rebate1[1], DoubleKit.mul(amount,percent2+percent4+percent5));
				rebate1[2] = DoubleKit.add(rebate1[2], DoubleKit.mul(amount,percent3));
				rebate1[3] = 0;
				rebate1[4] = 0;
				logParams1.add(new Object[]{orderNum,goodsid,amount,percent1,rebate1[0],percent2,rebate1[1],percent3,rebate1[2],percent4,rebate1[3],percent5,rebate1[4]});
				//用户为普通用户，非黄金会员，有邀请用户，此时推荐人、DSH、社区负责人、一级分销享利
				rebate2[0] = DoubleKit.add(rebate1[0], DoubleKit.mul(amount,percent1));
				rebate2[1] = DoubleKit.add(rebate1[1], DoubleKit.mul(amount,percent2+percent5));
				rebate2[2] = DoubleKit.add(rebate1[2], DoubleKit.mul(amount,percent3));
				rebate2[3] = DoubleKit.add(rebate1[3], DoubleKit.mul(amount,percent4));
				rebate2[4] = 0;
				logParams2.add(new Object[]{orderNum,goodsid,amount,percent1,rebate2[0],percent2,rebate2[1],percent3,rebate2[2],percent4,rebate2[3],percent5,rebate2[4]});
				//用户为黄金会员，也没有邀请用户，此时推荐人、DSH、社区负责人、二级分销享利
				rebate3[0] = DoubleKit.add(rebate1[0], DoubleKit.mul(amount,percent1));
				rebate3[1] = DoubleKit.add(rebate1[1], DoubleKit.mul(amount,percent2+percent4));
				rebate3[2] = DoubleKit.add(rebate1[2], DoubleKit.mul(amount,percent3));
				rebate3[3] = 0;
				rebate3[4] = DoubleKit.add(rebate1[4], DoubleKit.mul(amount,percent5));
				logParams3.add(new Object[]{orderNum,goodsid,amount,percent1,rebate3[0],percent2,rebate3[1],percent3,rebate3[2],percent4,rebate3[3],percent5,rebate3[4]});
				//用户为黄金会员，有邀请用户，此时推荐人、DSH、社区负责人、一级分销、二级分销享利
				rebate4[0] = DoubleKit.add(rebate1[0], DoubleKit.mul(amount,percent1));
				rebate4[1] = DoubleKit.add(rebate1[1], DoubleKit.mul(amount,percent2));
				rebate4[2] = DoubleKit.add(rebate1[2], DoubleKit.mul(amount,percent3));
				rebate4[3] = DoubleKit.add(rebate1[3], DoubleKit.mul(amount,percent4));
				rebate4[4] = DoubleKit.add(rebate1[4], DoubleKit.mul(amount,percent5));
				logParams4.add(new Object[]{orderNum,goodsid,amount,percent1,rebate4[0],percent2,rebate4[1],percent3,rebate4[2],percent4,rebate4[3],percent5,rebate4[4]});
			}
		}
		//如果消费的返利商品金额为0，则不处理
		if(totalAmount==0)return;
		//用户ID
		int userid = user.getInt("id");
		//用户注册邀请人ID
		int inviteUserid = user.getInt("inviteUserid");
		if(user.getInt("level")==UserCode.UserLevel.LEVEL1){
			//查询用户以前购买并签收（在线支付）的有返利的商品所消费的金额（不包括本次消费的订单金额）
			Record history = Db.findFirst("SELECT IFNULL(SUM(amount),0) amount"
					+ " FROM t_bus_order_list bol WHERE isRebate=1 AND EXISTS("
					+ " SELECT 1"
					+ " FROM t_bus_order bo"
					+ " INNER JOIN t_bus_order_log bolog ON bo.orderNum=bolog.orderNum"
					+ " WHERE bolog.type=? AND bo.userid=? AND bo.orderNum=bol.orderNum AND bo.orderNum!=?)",
					OrderCode.OrderLogType.SIGN,userid,orderNum);
			if(history!=null){
				//加上本次所消费的金额
				totalAmount = DoubleKit.add(totalAmount, history.getDouble("amount"));
			}
			//用户为普通会员时
			double level2Line = SysConfig.getLevel2Line();
			if(totalAmount>=level2Line){
				//当本次所购的开启返利的商品的消费总金额达到黄金会员线的时候
				//1.更新用户会员等级为黄金会员，并生成唯一邀请码保存（根据用户ID生成，可逆）
				Db.update("UPDATE t_bus_user SET level=?,inviteCode=? WHERE id=? AND level=?",UserCode.UserLevel.LEVEL2,InviteCodeKit.toSerialCode(userid),userid,UserCode.UserLevel.LEVEL1);
				//2.记录用户会员等级变化日志
				Db.update("INSERT INTO t_bus_user_level_log(userid,fromLevel,toLevel,flag,`describe`,fromOrderNum) VALUES(?,?,?,?,?,?)",userid,UserCode.UserLevel.LEVEL1,UserCode.UserLevel.LEVEL2,UserCode.UserLevelLogFlag.CONSUME,"消费",orderNum);
			}
			if(inviteUserid==0){
				//如果用户注册时没有邀请人，则本次购物所有返利将由推荐人、DSH、社区负责人享利
				//1.记录分销日志1
				Db.batch(logSql, parseParams(logParams1), logParams1.size());
			}else{
				//如果用户注册时有邀请人，则本次购物所有返利将由推荐人、DSH、社区负责人、一级分销享利
				//1.更新一级分销用户的“实惠币金额”
				User inviteUser = User.me().findById(inviteUserid);
				if(inviteUser==null){
					throw new Exception("用户（用户ID："+userid+"）的注册邀请人（用户ID："+inviteUserid+"）找不到！");
				}
				//此处使用行锁定的方式更新，防止并发
				if(Db.update("UPDATE t_bus_user SET money=money+? WHERE id=? AND money=?",rebate2[3],inviteUserid,inviteUser.getDouble("money"))!=1){
					throw new Exception("用户（用户ID："+userid+"）的注册邀请人（用户ID："+inviteUserid+"）更新money时出错！");
				}
				//2.记录一级分销用户的“实惠币金额”变动日志（记录订单号）
				Db.update("INSERT INTO t_bus_user_value_log(userid,amount,type,flag,`describe`,fromUserid,fromOrderNum) VALUES(?,?,?,?,?,?,?)",inviteUserid,rebate2[3],1,UserCode.UserValueLogFlag.CONSUME_UNDER,"下线用户消费",userid,orderNum);
				//3.记录分销日志2
				Db.batch(logSql, parseParams(logParams2), logParams2.size());
			}
		}else if(user.getInt("level")==UserCode.UserLevel.LEVEL2){
			//用户为黄金会员时
			if(inviteUserid==0){
				//如果用户注册时没有邀请人，则本次购物所有返利将由推荐人、DSH、社区负责人、二级分销享利
				//1.更新二级分销用户（即当前用户）的“实惠币金额”
				//此处使用行锁定的方式更新，防止并发
				if(Db.update("UPDATE t_bus_user SET money=money+? WHERE id=? AND money=?",rebate3[4],userid,user.getDouble("money"))!=1){
					throw new Exception("用户（用户ID："+userid+"）更新money时出错！");
				}
				//2.记录二级分销用户（即当前用户）的“实惠币金额”变动日志（记录订单号）
				Db.update("INSERT INTO t_bus_user_value_log(userid,amount,type,flag,`describe`,fromOrderNum) VALUES(?,?,?,?,?,?)",userid,rebate3[4],1,UserCode.UserValueLogFlag.CONSUME_SELF,"消费",orderNum);
				//3.记录分销日志3
				Db.batch(logSql, parseParams(logParams3), logParams3.size());
			}else{
				//如果用户注册时有邀请人，则本次购物所有返利将由推荐人、DSH、社区负责人、一级分销、二级分销享利
				//1.更新一级分销用户和二级分销用户（即当前用户）的“实惠币金额”
				User inviteUser = User.me().findById(inviteUserid);
				if(inviteUser==null){
					throw new Exception("用户（用户ID："+userid+"）的注册邀请人（用户ID："+inviteUserid+"）找不到！");
				}
				//此处使用行锁定的方式更新，防止并发
				if(Db.update("UPDATE t_bus_user SET money=money+? WHERE id=? AND money=?",rebate4[3],inviteUserid,inviteUser.getDouble("money"))!=1){
					throw new Exception("用户（用户ID："+userid+"）的注册邀请人（用户ID："+inviteUserid+"）更新money时出错！");
				}
				if(Db.update("UPDATE t_bus_user SET money=money+? WHERE id=? AND money=?",rebate4[4],userid,user.getDouble("money"))!=1){
					throw new Exception("用户（用户ID："+userid+"）更新money时出错！");
				}
				//2.记录一级分销用户和二级分销用户（即当前用户）的“实惠币金额”变动日志（记录订单号）
				Db.update("INSERT INTO t_bus_user_value_log(userid,amount,type,flag,`describe`,fromUserid,fromOrderNum) VALUES(?,?,?,?,?,?,?)",inviteUserid,rebate4[3],1,UserCode.UserValueLogFlag.CONSUME_UNDER,"下线用户消费",userid,orderNum);
				Db.update("INSERT INTO t_bus_user_value_log(userid,amount,type,flag,`describe`,fromOrderNum) VALUES(?,?,?,?,?,?)",userid,rebate4[4],1,UserCode.UserValueLogFlag.CONSUME_SELF,"消费",orderNum);
				//3.记录分销日志4
				Db.batch(logSql, parseParams(logParams4), logParams4.size());
			}
		}
	}
	
	/**
	 * 将list<object[]>集合转换为object[][]
	 * @param params list<object[]>集合
	 */
	private Object[][] parseParams(List<Object[]> params){
		if(params!=null){
			Object[][] result = new Object[params.size()][];
			for(int index = 0;index<params.size();index++){
				result[index] = params.get(index);
			}
			return result;
		}
		return null;
	}
	
	/**
	 * 处理实惠币抵用订单金额情况
	 * @param selfOrder
	 * @param storeOrder
	 * @return forwardFlag 1:跳转到支付页面，2：跳转到订单列表
	 */
	@Before(Tx.class)
	public int doRedeem(Order storeOrder,Order selfOrder,String storeGoodsIds,String selfGoodsIds,String storeCounts,
			String selfCounts,int userid,int isRedeem) throws Exception{
		int forwardFlag = 1;
		//查询用户信息
		User user = User.me().findById(userid);
		double userMoney = user.get("money");
		//店铺订单抵用金额
		double storeRedeemMoney = 0;
		//自营订单抵用金额
		double selfRedeemMoney = 0;
		String sql = "INSERT INTO t_bus_user_value_log(userid,amount,type,flag,`describe`,`data`,fromUserid,fromOrderNum) VALUES(?,?,?,?,?,?,?,?)";
		/**
		 * 只有店铺商品
		 */
		if(storeOrder != null && selfOrder == null){
			double orderAmount = Double.valueOf(storeOrder.get("amount"));
			//判断是否是在线支付
			if(storeOrder.getInt("payType") == OrderCode.OrderPayType.ON_LINE){
				if(isRedeem == 1 && userMoney > 0){
					//订单金额大于用户实惠币，抵用金额为用户实惠币，用户实惠币改为0(需要支付)
					if(orderAmount > userMoney) {
						storeRedeemMoney = userMoney;
						if(updateUserMoney(userid,0,userMoney) == 1){
							storeOrder.set("redeemMoney", storeRedeemMoney).set("isRedeem", "1");
						} else {
							throw new Exception("更新用户money失败");
						}
						forwardFlag = 1;
					}
					//订单金额等于用户实惠币，抵用金额为用户实惠币/订单金额，用户实惠币改为0(不需要支付)
					else if(orderAmount == userMoney){
						if(updateUserMoney(userid,storeRedeemMoney,userMoney) == 1){
							storeOrder.set("redeemMoney", storeRedeemMoney).set("isRedeem", "1").set("payState", OrderCode.OrderPayState.HAD_PAY);
						} else {
							throw new Exception("更新用户money失败");
						}
						forwardFlag = 2;
					}
					//订单金额小于用户实惠币，抵用金额为订单金额，用户实惠币改为“用户实惠币-订单金额”(不需要支付)
					else if(orderAmount < userMoney){
						storeRedeemMoney = orderAmount;
						if(updateUserMoney(userid,DoubleKit.sub(userMoney, orderAmount),userMoney) == 1){
							storeOrder.set("redeemMoney", storeRedeemMoney).set("isRedeem", "1").set("payState", OrderCode.OrderPayState.HAD_PAY);
						} else {
							throw new Exception("更新用户money失败");
						}
						forwardFlag = 2;
					}
					if(Db.update(sql,userid,storeRedeemMoney,2,UserCode.UserValueLogFlag.CONSUME_REDEEM,"实惠币抵用便利店订单金额","",0,storeOrder.getStr("orderNum"))!=1){
						throw new Exception("记录用户实惠币变化日志失败");
					}
				}
			} else {
				forwardFlag = 2;
			}
			//保存订单
			save(storeOrder, storeGoodsIds.split(","), storeCounts.split(","));
			if(storeOrder.getInt("payType")==OrderCode.OrderPayType.ON_LINE){
				log(storeOrder.getStr("orderNum"),OrderCode.OrderLogType.SAVE,"用户", OrderCode.OrderLogType.SAVE_ACTION, "订单已提交，请尽快支付");
			}else{
				log(storeOrder.getStr("orderNum"),OrderCode.OrderLogType.SAVE,"用户", OrderCode.OrderLogType.SAVE_ACTION, "订单已提交，等待系统确认");
			}
		}else
		/**
		 * 只有自营商品
		 */
		if(selfOrder != null && storeOrder == null){
			double orderAmount = Double.valueOf(selfOrder.get("amount"));
			//抵用标志==1,处理实惠币抵用情况
			if(isRedeem == 1 && userMoney > 0){
				//订单金额大于用户实惠币，抵用金额为用户实惠币，用户实惠币改为0(需要支付)
				if(orderAmount > userMoney) {
					selfRedeemMoney = userMoney;
					if(updateUserMoney(userid,0,userMoney) == 1){
						selfOrder.set("redeemMoney", selfRedeemMoney).set("isRedeem", "1");
					} else {
						throw new Exception("更新用户money失败");
					}
					forwardFlag = 1;
				}
				//订单金额等于用户实惠币，抵用金额为用户实惠币/订单金额，用户实惠币改为0(不需要支付)
				else if(orderAmount == userMoney){
					if(updateUserMoney(userid,selfRedeemMoney,userMoney) == 1){
						selfOrder.set("redeemMoney", selfRedeemMoney).set("isRedeem", "1").set("payState", OrderCode.OrderPayState.HAD_PAY);
					} else {
						throw new Exception("更新用户money失败");
					}
					forwardFlag = 2;
				}
				//订单金额小于用户实惠币，抵用金额为订单金额，用户实惠币改为“用户实惠币-订单金额”(不需要支付)
				else if(orderAmount < userMoney){
					selfRedeemMoney = orderAmount;
					if(updateUserMoney(userid,DoubleKit.sub(userMoney, orderAmount),userMoney) == 1){
						selfOrder.set("redeemMoney", selfRedeemMoney).set("isRedeem", "1").set("payState", OrderCode.OrderPayState.HAD_PAY);
					} else {
						throw new Exception("更新用户money失败");
					}
					forwardFlag = 2;
				}
			}
			if(Db.update(sql,userid,selfRedeemMoney,2,UserCode.UserValueLogFlag.CONSUME_REDEEM,"实惠币抵用直营订单金额","",0,selfOrder.getStr("orderNum"))!=1){
				throw new Exception("记录用户实惠币变化日志失败");
			}
			//保存订单
			save(selfOrder, selfGoodsIds.split(","), selfCounts.split(","));
			if(selfOrder.getInt("payType")==OrderCode.OrderPayType.ON_LINE){
				log(selfOrder.getStr("orderNum"),OrderCode.OrderLogType.SAVE,"用户", OrderCode.OrderLogType.SAVE_ACTION, "订单已提交，请尽快支付");
			}else{
				log(selfOrder.getStr("orderNum"),OrderCode.OrderLogType.SAVE,"用户", OrderCode.OrderLogType.SAVE_ACTION, "订单已提交，等待系统确认");
			}
		}else
		/**
		 * 店铺商品和自营商品同时存在
		 * 先抵用自营商品的金额，如果还有剩余，再抵用店铺商品的金额
		 */
		if(storeOrder != null && selfOrder != null){
			double storeAmount = Double.valueOf(storeOrder.getStr("amount"));
			double selfAmount = Double.valueOf(selfOrder.getStr("amount"));
			//抵用标志==1,处理实惠币抵用情况
			if(isRedeem == 1 && userMoney > 0){
				//如果店铺订单的支付方式为在线支付，订单金额为“店铺订单金额+自营订单金额”
				if(storeOrder.getInt("payType") == OrderCode.OrderPayType.ON_LINE){
					//自营订单金额大于用户实惠币，抵用金额为用户实惠币，用户实惠币改为0(需要支付)
					if(selfAmount > userMoney) {
						selfRedeemMoney = userMoney;
						if(updateUserMoney(userid,0,userMoney) == 1){
							selfOrder.set("redeemMoney", selfRedeemMoney).set("isRedeem", "1");
						} else {
							throw new Exception("更新用户money失败");
						}
						forwardFlag = 1;
					}
					//自营订单金额等于用户实惠币，抵用金额为用户实惠币/订单金额，用户实惠币改为0(需要支付)
					else if(selfAmount == userMoney){
						if(updateUserMoney(userid,selfRedeemMoney,userMoney) == 1){
							selfOrder.set("redeemMoney", selfRedeemMoney).set("isRedeem", "1").set("payState", OrderCode.OrderPayState.HAD_PAY);
						} else {
							throw new Exception("更新用户money失败");
						}
						forwardFlag = 1;
					}
					//自营订单金额小于用户实惠币，抵用金额为自营订单金额，用户实惠币改为“用户实惠币-订单金额”，再把用户剩余实惠币与店铺订单的金额进行比较
					else if(selfAmount < userMoney){
						selfRedeemMoney = selfAmount;
						//减去自营订单金额后用户剩余实惠币
						double userSurplusMoney = DoubleKit.sub(userMoney, selfAmount);
						if(updateUserMoney(userid, userSurplusMoney, userMoney) == 1){
							selfOrder.set("redeemMoney", selfRedeemMoney).set("isRedeem", "1").set("payState", OrderCode.OrderPayState.HAD_PAY);
						} else {
							throw new Exception("更新用户money失败");
						}
						//店铺订单金额大于用户剩余实惠币，抵用金额为用户剩余实惠币，用户实惠币改为0(需要支付)
						if(storeAmount > userSurplusMoney){
							storeRedeemMoney = userSurplusMoney;
							if(updateUserMoney(userid,0,userSurplusMoney) == 1){
								storeOrder.set("redeemMoney", storeRedeemMoney).set("isRedeem", "1");
							} else {
								throw new Exception("更新用户money失败");
							}
							forwardFlag = 1;
						}
						//店铺订单金额等于用户剩余实惠币，抵用金额为用户剩余实惠币/订单金额，用户实惠币改为0(不需要支付)
						else if(storeAmount == userSurplusMoney){
							storeRedeemMoney = userMoney;
							if(updateUserMoney(userid, 0, userSurplusMoney) == 1){
								storeOrder.set("redeemMoney", storeRedeemMoney).set("isRedeem", "1").set("payState", OrderCode.OrderPayState.HAD_PAY);
							} else {
								throw new Exception("更新用户money失败");
							}
							forwardFlag = 2;
						}
						//店铺订单金额小于用户剩余实惠币，抵用金额为店铺订单金额，用户剩余实惠币改为“用户剩余实惠币-订单金额”(不需要支付)
						else if(storeAmount < userSurplusMoney){
							storeRedeemMoney = storeAmount;
							if(updateUserMoney(userid, DoubleKit.sub(userSurplusMoney, storeRedeemMoney), userSurplusMoney) == 1){
								storeOrder.set("redeemMoney", storeRedeemMoney).set("isRedeem", "1").set("payState", OrderCode.OrderPayState.HAD_PAY);
							} else {
								throw new Exception("更新用户money失败");
							}
							forwardFlag = 2;
						}
					}
				} else {
					//订单金额大于用户实惠币，抵用金额为用户实惠币，用户实惠币改为0
					if(selfAmount > userMoney) {
						selfRedeemMoney = userMoney;
						if(updateUserMoney(userid,0,userMoney) == 1){
							storeOrder.set("redeemMoney", selfRedeemMoney).set("isRedeem", "1");
						} else {
							throw new Exception("更新用户money失败");
						}
						forwardFlag = 1;
					}
					//订单金额等于用户实惠币，抵用金额为用户实惠币/订单金额，用户实惠币改为0(不需要支付)
					else if(selfAmount == userMoney){
						if(updateUserMoney(userid,selfRedeemMoney,userMoney) == 1){
							storeOrder.set("redeemMoney", selfRedeemMoney).set("isRedeem", "1").set("payState", OrderCode.OrderPayState.HAD_PAY);
						} else {
							throw new Exception("更新用户money失败");
						}
						forwardFlag = 2;
					}
					//订单金额小于用户实惠币，抵用金额为订单金额，用户实惠币改为“用户实惠币-订单金额”(不需要支付)
					else if(selfAmount < userMoney){
						selfRedeemMoney = selfAmount;
						if(updateUserMoney(userid,DoubleKit.sub(userMoney, selfAmount),userMoney) == 1){
							storeOrder.set("redeemMoney", selfRedeemMoney).set("isRedeem", "1").set("payState", OrderCode.OrderPayState.HAD_PAY);
						} else {
							throw new Exception("更新用户money失败");
						}
						forwardFlag = 2;
					}
				}
				if(Db.update(sql,userid,selfRedeemMoney,2,UserCode.UserValueLogFlag.CONSUME_REDEEM,"实惠币抵用直营订单金额","",0,selfOrder.getStr("orderNum"))!=1){
					throw new Exception("记录用户实惠币变化日志失败");
				}
				if(Db.update(sql,userid,storeRedeemMoney,2,UserCode.UserValueLogFlag.CONSUME_REDEEM,"实惠币抵用便利店订单金额","",0,storeOrder.get("orderNum"))!=1){
					throw new Exception("记录用户实惠币变化日志失败");
				}
			}
			//保存店铺商品订单
			save(storeOrder, storeGoodsIds.split(","), storeCounts.split(","));
			//根据订单支付方式不同，记录日志不同
			if(storeOrder.getInt("payType")==OrderCode.OrderPayType.ON_LINE){
				log(storeOrder.getStr("orderNum"),OrderCode.OrderLogType.SAVE,"用户", OrderCode.OrderLogType.SAVE_ACTION, "订单已提交，请尽快支付");
			}else{
				log(storeOrder.getStr("orderNum"),OrderCode.OrderLogType.SAVE,"用户", OrderCode.OrderLogType.SAVE_ACTION, "订单已提交，等待系统确认");
			}
			//保存自营商品订单
			save(selfOrder, selfGoodsIds.split(","), selfCounts.split(","));
			log(selfOrder.getStr("orderNum"),OrderCode.OrderLogType.SAVE,"用户", OrderCode.OrderLogType.SAVE_ACTION, "订单已提交，请尽快支付");
		}
		return forwardFlag;
	}
}
